08. Configuration
BaseModel.model_config
用于配置 BaseModel 的行为
from pydantic import BaseModel, ConfigDict, ValidationError
class Model(BaseModel):
model_config = ConfigDict(str_max_length=10)
v: str
try:
m = Model(v='x' * 20)
except ValidationError as e:
print(e)
"""
1 validation error for Model
v
String should have at most 10 characters [type=string_too_long, input_value='xxxxxxxxxxxxxxxxxxxx', input_type=str]
"""
当然,直接在类参数中传入配置项也是可行的
from pydantic import BaseModel, ValidationError
class Model(BaseModel, extra='forbid'):
a: str
try:
Model(a='spam', b='oh no')
except ValidationError as e:
print(e)
"""
1 validation error for Model
b
Extra inputs are not permitted [type=extra_forbidden, input_value='oh no', input_type=str]
"""
使用 dataclass 的时候,也能在装饰器中传入设置项
from datetime import datetime
from pydantic import ConfigDict, ValidationError
from pydantic.dataclasses import dataclass
config = ConfigDict(str_max_length=10, validate_assignment=True)
@dataclass(config=config)
class User:
id: int
name: str = 'John Doe'
signup_ts: datetime = None
user = User(id='42', signup_ts='2032-06-21T12:00')
try:
user.name = 'x' * 20
except ValidationError as e:
print(e)
"""
1 validation error for User
name
String should have at most 10 characters [type=string_too_long, input_value='xxxxxxxxxxxxxxxxxxxx', input_type=str]
"""
在 dataclass
或 TypedDict
中使用设置项
使用 __pydantic_config__
from dataclasses import dataclass
from datetime import datetime
from pydantic import ConfigDict
@dataclass
class User:
__pydantic_config__ = ConfigDict(strict=True)
id: int
name: str = 'John Doe'
signup_ts: datetime = None
Alternatively, the with_config
decorator can be used to comply with type checkers.
from typing_extensions import TypedDict
from pydantic import ConfigDict, with_config
@with_config(ConfigDict(str_to_lower=True))
class Model(TypedDict):
x: str
全局性配置
可以创建一个继承自 BaseModel
的基础 model 类,达成全局性配置的目的
from pydantic import BaseModel, ConfigDict
class Parent(BaseModel):
model_config = ConfigDict(extra='allow')
class Model(Parent):
x: str
m = Model(x='foo', y='bar')
print(m.model_dump())
#> {'x': 'foo', 'y': 'bar'}
If you add a model_config
to the Model
class, it will merge with the model_config
from Parent
:
from pydantic import BaseModel, ConfigDict
class Parent(BaseModel):
model_config = ConfigDict(extra='allow')
class Model(Parent):
model_config = ConfigDict(str_to_lower=True) # (1)!
x: str
m = Model(x='FOO', y='bar')
print(m.model_dump())
#> {'x': 'foo', 'y': 'bar'}
print(m.model_config)
#> {'extra': 'allow', 'str_to_lower': True}
配置项
- title
- str,The title for the generated JSON schema, defaults to the model's name
- str_to_lower、str_to_upper
- bool,是否将所有字符串大写 / 小写
- str_strip_whitespace
- bool,是否移除前后空白字符
- str_min_length、str_max_length
- int,字符串最短 / 最长长度
- extra
- ExtraValues,在初始化 model 时,针对额外传入的参数的行为
allow
- Allow any extra attributes.forbid
- Forbid any extra attributes. 遇到额外字段会报错ignore
- Ignore any extra attributes. Default value.
- frozen
- bool,model 是否不变(faux-immutable)
- i.e. whether
__setattr__
is allowed, and also generates a__hash__()
method for the model. This makes instances of the model potentially hashable if all the attributes are hashable.
- populate_by_name
- bool,Whether an aliased field may be populated by its name as given by the model attribute, as well as the alias. Defaults to
False
. - bool,针对别名字段,能否使用原名来填充 model
- bool,Whether an aliased field may be populated by its name as given by the model attribute, as well as the alias. Defaults to
from pydantic import BaseModel, ConfigDict, Field
class User(BaseModel):
model_config = ConfigDict(populate_by_name=True)
name: str = Field(alias='full_name')
age: int
user = User(full_name='John Doe', age=20) # The model is populated by the alias 'full_name'.
print(user)
#> name='John Doe' age=20
user = User(name='John Doe', age=20) # 如果 populate_by_name=False,则会报错
print(user)
#> name='John Doe' age=20
- use_enum_values
- bool,是否使用枚举的值本身来填充 models,而不是枚举值
- This may be useful if you want to serialize
model.model_dump()
later. Defaults toFalse
.
from enum import Enum
from typing import Optional
from pydantic import BaseModel, ConfigDict, Field
class SomeEnum(Enum):
FOO = 'foo'
BAR = 'bar'
BAZ = 'baz'
class SomeModel(BaseModel):
model_config = ConfigDict(use_enum_values=True)
some_enum: SomeEnum
another_enum: Optional[SomeEnum] = Field(default=SomeEnum.FOO, validate_default=True)
model1 = SomeModel(some_enum=SomeEnum.BAR)
print(model1.model_dump())
# {'some_enum': 'bar', 'another_enum': 'foo'}
model2 = SomeModel(some_enum=SomeEnum.BAR, another_enum=SomeEnum.BAZ)
print(model2.model_dump())
#> {'some_enum': 'bar', 'another_enum': 'baz'}
# 如果设置为False的话,则会输出
#> {'some_enum': <SomeEnum.BAR: 'bar'>, 'another_enum': <SomeEnum.FOO: 'foo'>}
#> {'some_enum': <SomeEnum.BAR: 'bar'>, 'another_enum': <SomeEnum.BAZ: 'baz'>}
- validate_assignment
- bool,当 model 值改变时,是否重新 validate 一遍
- Pydantic 默认的行为是:只在创建时验证
from pydantic import BaseModel, ValidationError
class User(BaseModel, validate_assignment=True):
name: str
user = User(name='John Doe')
print(user)
#> name='John Doe'
try:
user.name = 123
except ValidationError as e:
print(e)
'''
1 validation error for User
name
Input should be a valid string [type=string_type, input_value=123, input_type=int]
'''
- arbitrary_types_allowed
- bool,字段类型是否允许使用任意类型
from pydantic import BaseModel, ConfigDict
# This is not a pydantic model, it's an arbitrary class
class Pet:
def __init__(self, name: str):
self.name = name
class Model(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
pet: Pet
owner: str
TBD